/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.BluetoothChat;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This is the main Activity that displays the current chat session.
 */
public class MainActivity extends Activity {
	// Debugging
	private static final String TAG = "MainActivity";
	private static final boolean D = true;

	// Message types sent from the BluetoothChatService Handler
	public static final int MESSAGE_STATE_CHANGE = 1;
	public static final int MESSAGE_READ = 2;
	public static final int MESSAGE_WRITE = 3;
	public static final int MESSAGE_WRITE_AUDIO = 6;
	public static final int MESSAGE_DEVICE_NAME = 4;
	public static final int MESSAGE_TOAST = 5;

	// Key names received from the BluetoothChatService Handler
	public static final String DEVICE_NAME = "device_name";
	public static final String TOAST = "toast";

	// Intent request codes
	private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
	private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
	private static final int REQUEST_ENABLE_BT = 3;

	// Layout Views
	private ListView mConversationView;
	private EditText mOutEditText;
	private Button button_sendtext;
	private Button button_sendmusic;
	private Button button_server;
	private Button button_client;
	private BluetoothServer bluetoothServer;
	private BluetoothTextServer bluetoothTextServer;
	private BluetoothClient bluetoothClient;
	private BluetoothTextClient bluetoothTextClient;
	// Name of the connected device
	private String mConnectedDeviceName = null;
	// Array adapter for the conversation thread
	private ArrayAdapter<String> mConversationArrayAdapter;
	// String buffer for outgoing messages
	private StringBuffer mOutStringBuffer;
	// Local Bluetooth adapter
	private BluetoothAdapter mBluetoothAdapter = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (D)
			Log.e(TAG, "+++ ON CREATE +++");

		// Set up the window layout
		setContentView(R.layout.main_model);

		// Get local Bluetooth adapter
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

		// If the adapter is null, then Bluetooth is not supported
		if (mBluetoothAdapter == null) {
			Toast.makeText(this, "Bluetooth is not available",
					Toast.LENGTH_LONG).show();
			finish();
			return;
		}
		button_sendtext = (Button) findViewById(R.id.button_send);

		button_sendtext.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				// Send a message using content of the edit text widget
				TextView view = (TextView) findViewById(R.id.edit_text_out);
				// view.setVisibility(View.INVISIBLE);
				String message = view.getText().toString();
				sendMessage(message);

			}
		});
		button_sendmusic = (Button) findViewById(R.id.button_audio);

		button_sendmusic.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {

				setupAudio();
			}
		});
		button_server = (Button) findViewById(R.id.button_ser);

		button_server.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				bluetoothServer = new BluetoothServer(MainActivity.this,
						mHandler);
				bluetoothServer.setUpServer();
				button_server.setEnabled(false);
				button_client.setEnabled(false);
				bluetoothTextServer = new BluetoothTextServer(
						MainActivity.this, mHandler);
				bluetoothTextServer.setUpServer();
			}
		});
		button_client = (Button) findViewById(R.id.button_clt);

		button_client.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Intent mIntent = new Intent(MainActivity.this,
						DeviceListActivity.class);
				startActivityForResult(mIntent, REQUEST_CONNECT_DEVICE_SECURE);
			}
		});
	}

	public void setupAudio() {
		if (bluetoothServer != null) {
			InputStream is;
			try {
				is = getAssets().open("sing.mp3");
				bluetoothServer.sendAudioToAllClient(is);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	@Override
	public void onStart() {
		super.onStart();
		if (D)
			Log.e(TAG, "++ ON START ++");

		// If BT is not on, request that it be enabled.
		// setupChat() will then be called during onActivityResult
		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
			// Otherwise, setup the chat session
		}
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		// Stop the Bluetooth chat services
		if (bluetoothServer != null)
			bluetoothServer.stop();
		if (bluetoothClient != null) {
			bluetoothClient.stop();
		}
	}

	private void ensureDiscoverable() {
		if (D)
			Log.d(TAG, "ensure discoverable");
		if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
			Intent discoverableIntent = new Intent(
					BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
			discoverableIntent.putExtra(
					BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
			startActivity(discoverableIntent);
		}
	}

	/**
	 * Sends a message.
	 * 
	 * @param message
	 *            A string of text to send.
	 */
	private void sendMessage(String message) {
		bluetoothTextServer.sendTextToAllClient(message);
	}

	// The action listener for the EditText widget, to listen for the return key
	private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {
		public boolean onEditorAction(TextView view, int actionId,
				KeyEvent event) {
			// If the action is a key-up event on the return key, send the
			// message
			if (actionId == EditorInfo.IME_NULL
					&& event.getAction() == KeyEvent.ACTION_UP) {
				String message = view.getText().toString();
				sendMessage(message);
			}
			if (D)
				Log.i(TAG, "END onEditorAction");
			return true;
		}
	};
	PCMAudioRecoder audioPlayer;
	// The Handler that gets information back from the BluetoothChatService
	StringBuilder StringBuild_message = new StringBuilder();
	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 0:
				if (null != msg.obj) {
					StringBuild_message.append(msg.obj.toString() + "\n");
					final TextView actionBar = (TextView) findViewById(R.id.staute);
					actionBar.setText(StringBuild_message.toString());

				}
				break;
			case 1:
				button_sendmusic
						.setEnabled(button_sendmusic.isEnabled() ? false : true);// FIXME
				break;
			}
		}
	};

	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (D)
			Log.d(TAG, "onActivityResult " + resultCode);
		switch (requestCode) {
		case REQUEST_CONNECT_DEVICE_SECURE:
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {
				connectDevice(data, true);
			}
			break;
		case REQUEST_CONNECT_DEVICE_INSECURE:
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {
				connectDevice(data, false);
			}
			break;
		case REQUEST_ENABLE_BT:
			// // When the request to enable Bluetooth returns
			// if (resultCode == Activity.RESULT_OK) {
			// // Bluetooth is now enabled, so set up a chat session
			// setupChat();
			// setupAudio();
			// } else {
			// // User did not enable Bluetooth or an error occurred
			// Log.d(TAG, "BT not enabled");
			// Toast.makeText(this, R.string.bt_not_enabled_leaving,
			// Toast.LENGTH_SHORT).show();
			// finish();
			// }
		}
	}

	private void connectDevice(Intent data, boolean secure) {
		// Get the device MAC address
		String address = data.getExtras().getString(
				DeviceListActivity.EXTRA_DEVICE_ADDRESS);
		// Get the BluetoothDevice object
		BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
		bluetoothClient = new BluetoothClient(MainActivity.this, mHandler);
		bluetoothClient.config(null);
		bluetoothClient.connect(device);
		
		bluetoothTextClient = new BluetoothTextClient(MainActivity.this, mHandler);
		bluetoothTextClient.config(null);
		bluetoothTextClient.connect(device);
		
		button_client.setEnabled(false);
		button_sendtext.setEnabled(false);
		button_sendmusic.setEnabled(false);
		button_server.setEnabled(false);
		// Attempt to connect to the device

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.option_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent serverIntent = null;
		switch (item.getItemId()) {
		case R.id.secure_connect_scan:
			// Launch the DeviceListActivity to see devices and do scan
			serverIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
			return true;
		case R.id.insecure_connect_scan:
			// Launch the DeviceListActivity to see devices and do scan
			serverIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(serverIntent,
					REQUEST_CONNECT_DEVICE_INSECURE);
			return true;
		case R.id.discoverable:
			// Ensure this device is discoverable by others
			ensureDiscoverable();
			return true;
		}
		return false;
	}

}
